package com.etop.jansing.controller;

import com.etop.jansing.dto.ResourceDto;
import com.etop.jansing.entities.Role;
import com.etop.jansing.entities.User;
import com.etop.jansing.service.ResourceService;
import com.etop.jansing.service.RoleService;
import com.etop.jansing.service.UserService;
import com.etop.jansing.util.CommonUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * Created by jansing on 2015/10/18.
 */
@Controller
@RequestMapping("admin/user")
public class UserController extends BaseController {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private ResourceService resourceService;

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }

    /*
    DisabledAccountException（禁用的帐号）、
    LockedAccountException（锁定的帐号）、
    org.apache.shiro.authc.UnknownAccountException（错误的帐号，没有这个账号）、
    ExcessiveAttemptsException（登录失败次数过多）、
    org.apache.shiro.authc.IncorrectCredentialsException （错误的凭证，账号对但密码错）、
    ExpiredCredentialsException（过期的凭证）
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(User user, Model model, HttpSession session) {
        //使用shiro管理登录，会调用到MyRealm.doGetAuthenticationInfo(),可以在里面设置抛出各种异常
        SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword().toLowerCase()));

        //用shiro进行登陆逻辑，这里只需要取user对象放入session中。
        User loginUser = userService.login(user);
        if (loginUser == null) {
            return login();
        }

        //如果要实现，当该用户有查寻权限是才显示该菜单，可以传入这个用户的角色list，
        //修改CommonUtils.getResourceDto：只要有子资源/权限，则isSelected=true。
        //jsp页面就判断，只显示isSelected=true的。
        ResourceDto rootResourceDto = resourceService.getRootResource(null);
        session.setAttribute("rootResourceDto", rootResourceDto);
        session.setAttribute("loginUser", loginUser);
        return "redirect:list";
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(HttpSession session) {
        System.out.println("logout");
//        使用shiro 的 logout() ，它会自动将 HttpSession 给invalidate掉，
//        所以如果在下面这句代码之后再用到session的话，会抛出异常
//        org.apache.shiro.session.UnknownSessionException
//        SecurityUtils.getSubject().logout();

//        同样的，执行 HttpSession 的invalidate() 也会自动把shiro的会话给 stop 掉
        session.invalidate();
//        if(session.getAttribute("user")!=null){
//            System.out.println("after not null");
//        }
//
        return "redirect:login";
    }

    /**
     * todo 分页
     *
     * @param model
     * @return
     */
    @RequiresPermissions("user:list")
    @RequestMapping(value = "/list", produces = "text/html;charset=utf-8")
    public String list(Model model) {
        List<User> userList = userService.getUserList();
        model.addAttribute("userList", userList);
//        session.setAttribute("rootResource", rootResource);
        return "admin/user/list";
    }

    //添加与修改同在一个页面，且同在一个post方法处理请求
    @RequiresPermissions("user:add")
    @RequestMapping(value = "/add", produces = "text/html;charset=utf-8", method = RequestMethod.GET)
    public String add(Model model) {
        List<Role> roleList = roleService.getAllRoles();
        model.addAttribute("user", new User());
        model.addAttribute("roleList", roleList);
        return "admin/user/edit";
    }

    @RequiresPermissions("user:update")
    @RequestMapping(value = "/edit/{id}", produces = "text/html;charset=utf-8", method = RequestMethod.GET)
    public String edit(@PathVariable("id") long id, Model model) {
        User user = userService.getById(id);
        List<Role> roleList = roleService.getAllRoles();
        model.addAttribute("user", user);
        model.addAttribute("roleList", roleList);
        return "admin/user/edit";
    }

    @RequiresPermissions("user:edit")
    @RequestMapping(value = "/edit", method = RequestMethod.POST, produces = "text/html;charset=utf-8")
    public String edit(@ModelAttribute("user") User user, HttpServletRequest request) {
        String[] rids = request.getParameterValues("rids");
        userService.saveOrUpdate(user, rids);
        return "redirect:list";
    }


    @RequiresPermissions("user:delete")
    @RequestMapping(value = "/delete/{id}", produces = "text/html;charset=utf-8")
    public String delete(@PathVariable("id") long id) {
        userService.delete(id);
        return "redirect:/admin/user/list";
    }


//    public String updatePassword(User user){
//        因为使用了缓存，在一定时间内缓存都会生效。
//        所以如果更新了密码，则要把缓存中这个用户的账号密码给清空掉。
//        ShiroUtils.clearCurrentUserCachedAuthenticationInfo();


    //同样的，如果删改某个用户有什么角色、删改角色、删改角色有什么资源权限对、增删资源权限对、删改资源、删改权限时
    //都需要将角色权限的缓存清空掉
//        ShiroUtils.clearCurrentUserCachedAuthorizationInfo();
//        return null;
//
//    }

}
